#!/usr/bin/env python
#Copyright (c) 2011 Isaac Dawson (WBTS Project)
#Permission is hereby granted, free of charge, to any person obtaining a copy 
#of this software and associated documentation files (the "Software"), to deal 
#in the Software without restriction, including without limitation the rights 
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
#copies of the Software, and to permit persons to whom the Software is furnished
#to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
#THE SOFTWARE.
import cgi
import time
import copy

from twisted.web import resource, server, static
from twisted.internet import defer
from twisted.python import log
from zope.interface import implements

# for some common filtering and response functions.
from wbts.utils.web_utils import clean_result, not_empty
from wbts.utils import xml_utils

def return_xml(export_data, request, needs_decode):
    xml_data = xml_utils.XMLDict()
    i = 0
    for result in export_data:
        copy_result = copy.deepcopy(result)
        try:
            clean_result(copy_result, request, needs_decode)
        except Exception, msg:
            log.err("ERROR An exception occurred getting results: ")
            log.msg(msg)
            request.setHeader("content-type", "text/html")
            request.write("An error occurred getting results.")
            request.finish()
            return
        xml_data.dictToXMLFragment(copy_result, i)
        i += 1
    
    request.setHeader("content-type", "application/download")
    file_name = "wbtsxml_data-%s.xml"%time.strftime("%Y%m%d%H%M%S")
    request.setHeader("content-disposition",
                      "attachment; filename=%s"%file_name)
    
    request.write(xml_data.toString())
    xml_data.close() # close out our memory file...
    request.finish()
    return

def return_raw(export_data, request, needs_decode=None):
    return_data = ""
    line_marker = '-'*80
    for result in export_data:
        # make a copy so we don't accidentally mess up our result in memory
        copy_result = copy.deepcopy(result)
        try:
            clean_result(copy_result, request, needs_decode)
            for var,val in copy_result.items():
                return_data += "%s: %s\r\n"%(var,val)
            return_data += "\r\n%s\r\n"%line_marker
        except Exception, msg:
            log.err("ERROR An exception occurred getting results: ")
            log.msg(msg)
            request.setHeader("content-type", "text/html")
            request.write("An error occurred getting results.")
            request.finish()
            return
        
            
    request.setHeader("content-type", "application/download")
    file_name = "raw_wbtsresults_data-%s.txt"%time.strftime("%Y%m%d%H%M%S")
    request.setHeader("content-disposition",
                      "attachment; filename=%s"%file_name)
    request.write(str(return_data))
    request.finish()
    return

class DownloadJsDbResults(resource.Resource):
    implements(resource.IResource)
    def __init__(self, service):
        """
        WBTS DB Tables
        """
        resource.Resource.__init__(self)
        self.mMgmtService = service
        self.needsDecoded = ["host", "target_host", "result", "expected_result",
                             "input", "output"]
        self.mDb = self.mMgmtService.mDbConn
        
    def _cb_Err(self, err, request):
        log.err("ERROR an error occured when attempting to download: %s"%err)
        return "An error occurred getting results"
           
    def render_GET(self, request):
        type = 'raw'
        dbname = ''
        d = defer.Deferred()
        if (not_empty(request.args, "type")):
            type = request.args["type"][0]
        
        if (not_empty(request.args, "dbname")):
            dbname = request.args["dbname"][0]
        
        try:
            db = self.mDb[dbname];
        except KeyError, msg:
            log.msg("Error finding db: "+dbname)
            #d.addErrback(self._cb_Err, request)
            request.setResponseCode(400)
            return "Incorrect DB supplied."
        except AttributeError, msg:
            log.msg("Error incorrect db supplied: "+dbname)
            request.setResponseCode(400)
            #d.addErrback(self._cb_Err, request)
            return "Incorrect DB supplied."
        
        d = db.find()
        if (type == 'raw'):
            d.addCallback(return_raw, request, self.needsDecoded)
        elif (type == 'xml'):
            d.addCallback(return_xml, request, self.needsDecoded)
        else:
            request.setResponseCode(400)
            return "Incorrect type supplied."
        
        d.addErrback(self._cb_Err, request)
        return server.NOT_DONE_YET

    render_POST = render_GET